package asem.ast.sentencias;

import genc.GenC;
import alex.Token;
import asem.TablaSimbolos;
import asem.excepciones.ExcepcionEntidadNoDeclarada;
import asem.excepciones.ExcepcionLlamadaInvalida;
import asem.tablaSimbolos.AtributoDeInstancia;
import asem.tablaSimbolos.Variable;
import asem.tablaSimbolos.tipo.Tipo;
import asem.tablaSimbolos.tipo.TipoClase;

public class NodoIDEncadenado {
	protected Token identificador;
	protected NodoIDEncadenado siguiente;

	public NodoIDEncadenado(Token t) {
		identificador = t;
		siguiente = null;
	}

	public void setSiguiente(NodoIDEncadenado sig) {
		siguiente = sig;
	}

	public Tipo chequeoSentencias(Variable var) {
		Tipo t = var.getTipo();

		if (!(t instanceof TipoClase))
			throw new ExcepcionLlamadaInvalida(t, identificador);

		AtributoDeInstancia a = TablaSimbolos.tabla.getClase(t.toString())
				.getAtributo(identificador.getLexema());

		if (a == null)
			throw new ExcepcionEntidadNoDeclarada(identificador, t.toString(),
					"atributo");

		Tipo r = a.getTipo();

		if (siguiente != null) {
			GenC.gen.loadref(Integer.toString(a.getOffset()),
					"Cargamos el valor de la varinst " + a.getNombre());
			r = siguiente.chequeoSentencias(a);
		} else {
			GenC.gen.swap("Swap para poder realizar el storeref ");
			GenC.gen.storeref(Integer.toString(a.getOffset()),
					"Se guarda el valor del tope de la pila en la variable "
							+ a.getNombre());
		}

		return r;
	}

	public NodoIDEncadenado getSiguiente() {
		return siguiente;
	}

	public Token getIdentificador() {
		return identificador;
	}

}
